package com.jhgsys.internal.sypq.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jhgsys.internal.dict.service.IDictService;
import com.jhgsys.internal.sypq.entity.*;
import com.jhgsys.internal.sypq.mapper.AttachmentFileMapper;
import com.jhgsys.internal.sypq.mapper.ModelAttachMapper;
import com.jhgsys.internal.sypq.mapper.TaskMapper;
import com.jhgsys.internal.sypq.params.FileParams;
import com.jhgsys.internal.sypq.params.ModelAttachAddParams;
import com.jhgsys.internal.sypq.params.WechatFinishParams;
import com.jhgsys.internal.sypq.params.WechatModelParams;
import com.jhgsys.internal.sypq.service.IModelAttachService;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.sypq.service.IProjectManagerService;
import com.jhgsys.internal.sypq.service.ISypqProjectService;
import com.jhgsys.internal.sypq.vo.CurUserProjInfoVO;
import com.jhgsys.internal.sypq.vo.ProjectVO;
import com.jhgsys.internal.sypq.vo.WechatAttachModelVO;
import com.jhgsys.internal.system.entity.User;
import com.jhgsys.internal.system.entity.UserRole;
import com.jhgsys.internal.system.service.IUserRoleService;
import org.apache.shiro.SecurityUtils;
import com.jhgsys.internal.common.entity.FebsConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.StringPool;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 附体 Service实现
 *
 * @author ganjun
 * @date 2024-11-20 17:18:55
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ModelAttachServiceImpl extends ServiceImpl<ModelAttachMapper, ModelAttach> implements IModelAttachService {

    @Resource
    private AttachmentFileMapper attachmentFileMapper;

    @Resource
    private IDictService dictService;

    @Resource
    private ISypqProjectService projectService;

    @Autowired
    IProjectManagerService projectManagerService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private TaskMapper taskMapper;

    /**
     * 查询（分页）
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param request QueryRequest
     * @param modelAttach modelAttach
     * @return IPage<ModelAttach>
    */
    @Override
    public IPage<ModelAttach> findModelAttachPage(QueryRequest request,  String demondFinishTime, String name, String statusSearch, String codeSearch) {
        LambdaQueryWrapper<ModelAttach> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelAttach::getDeletedFlg, 0);
        queryWrapper.orderByDesc(ModelAttach::getCreatedTime);
        //要求完成时间
        if(StringUtils.isNotEmpty(demondFinishTime)){
            String[] times = demondFinishTime.split(" - ");
            queryWrapper.between(ModelAttach::getDemandEnddate, times[0], times[1]);
        }
        //状态
        if(StringUtils.isNotBlank(statusSearch)){
            queryWrapper.eq(ModelAttach::getStatus, statusSearch);
        }
        //船模编号
        if(StringUtils.isNotBlank(codeSearch)){
            queryWrapper.eq(ModelAttach::getAttachCode, codeSearch);
        }
        //项目名称
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like(ModelAttach::getProjectName, name);
        }

        //角色判断
        CurUserProjInfoVO curUserProjInfoVO = getCurUserProjInfo();
        boolean isSysAdmin = curUserProjInfoVO.isSysAdmin();
        List<String> projCodeList = curUserProjInfoVO.getProjCodeList();
        //根据权限判断可以查看的项目相关的桨模
        if(!isSysAdmin){
            if(CollectionUtil.isNotEmpty(projCodeList)){
                queryWrapper.in(ModelAttach::getProjectCode, projCodeList);
            }else{
                projCodeList.add("0");
                queryWrapper.in(ModelAttach::getProjectCode, projCodeList);
            }
        }

        Page<ModelAttach> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        return this.page(page, queryWrapper);
    }

    /**
     * 导出
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param request QueryRequest
     * @param modelAttach modelAttach
     * @return IPage<ModelAttach>
     */
    @Override
    public List<ModelAttach> export(QueryRequest request,  String demondFinishTime, String name, String statusSearch, String codeSearch) {
        LambdaQueryWrapper<ModelAttach> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelAttach::getDeletedFlg, 0);
        queryWrapper.orderByDesc(ModelAttach::getCreatedTime);
        //要求完成时间
        if(StringUtils.isNotEmpty(demondFinishTime)){
            String[] times = demondFinishTime.split(" - ");
            queryWrapper.between(ModelAttach::getDemandEnddate, times[0], times[1]);
        }
        //状态
        if(StringUtils.isNotBlank(statusSearch)){
            queryWrapper.eq(ModelAttach::getStatus, statusSearch);
        }
        //船模编号
        if(StringUtils.isNotBlank(codeSearch)){
            queryWrapper.eq(ModelAttach::getAttachCode, codeSearch);
        }
        //名称
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like(ModelAttach::getProjectName, name);
        }
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 查询（所有）
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param modelAttach modelAttach
     * @return List<ModelAttach>
     */
    @Override
    public List<ModelAttach> findModelAttachList(ModelAttach modelAttach) {
	    LambdaQueryWrapper<ModelAttach> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelAttach::getDeletedFlg, 0);
        queryWrapper.eq(ModelAttach::getProjectCode,modelAttach.getProjectCode());
		// TODO 设置查询条件
		return this.baseMapper.selectList(queryWrapper);
    }

    /**
    * 根据ID查询
    * @author ganjun
    * @date 2024-11-20 17:18:55
    * @param id
    * @return ModelAttach
    */
    @Override
    public ModelAttach findModelAttachById(String id){
        return this.baseMapper.selectById(id);
    }

    @Override
    public List<FileParams> getModelShipAttachsByAttachId(String id, String fileType){
        LambdaQueryWrapper<AttachmentFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AttachmentFile::getDeletedFlg, 0);
        queryWrapper.eq(AttachmentFile::getVoucherCode, id);
        if(StringUtils.isNotEmpty(fileType)){
            queryWrapper.eq(AttachmentFile::getVoucherType, fileType);
        }

        queryWrapper.orderByDesc(AttachmentFile::getCreatedTime);
        List<AttachmentFile> attachs = attachmentFileMapper.selectList(queryWrapper);
        List<FileParams> files = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(attachs)){
            for(AttachmentFile attach : attachs){
                FileParams file = new FileParams();
                file.setFileName(attach.getFilename());
                file.setFilePath(attach.getFilepath());
                files.add(file);
            }
        }
        return files;

    }

    /**
     * 新增
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param modelAttach modelAttach
     */
    @Override
    @Transactional
    public void createModelAttach(ModelAttachAddParams params) {
        ModelAttach modelAttach = params.getModelAttach();
        modelAttach.setStatus(1);
        modelAttach.setStatusName(dictService.findDictLabel("MODEL_ATTACH_STATUS", "1"));
        modelAttach.setSourceName(dictService.findDictLabel("MODEL_ATTACH_SOURCE", modelAttach.getSource() + ""));
        modelAttach.setAttachTypeName(dictService.findDictLabel("MODEL_ATTACH_TYPE", modelAttach.getAttachType() + ""));
        this.save(modelAttach);

        //保存附件
        List<FileParams> files = params.getFileList();
        if(CollectionUtil.isNotEmpty(files)){
            for(FileParams file : files){
                AttachmentFile attach = new AttachmentFile();
                attach.setFilename(file.getFileName());
                attach.setFilepath(file.getFilePath());
                //2：附体的附件
                attach.setVoucherType("3");
                attach.setVoucherCode(modelAttach.getId());
                attachmentFileMapper.insert(attach);
            }
        }


    }

    /**
     * 修改
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param modelAttach modelAttach
     */
    @Override
    @Transactional
    public void updateModelAttach(ModelAttachAddParams params) {

        ModelAttach modelAttach = params.getModelAttach();
        modelAttach.setStatus(1);
        modelAttach.setStatusName(dictService.findDictLabel("MODEL_ATTACH_STATUS", "1"));
        modelAttach.setSourceName(dictService.findDictLabel("MODEL_ATTACH_SOURCE", modelAttach.getSource() + ""));
        modelAttach.setAttachTypeName(dictService.findDictLabel("MODEL_ATTACH_TYPE", modelAttach.getAttachType() + ""));
        this.updateById(modelAttach);
        //更新附件
        //1. 逻辑删除原有附件
        AttachmentFile attachmentFile = new AttachmentFile();
        attachmentFile.setDeletedFlg(FebsConstant.INVALID);
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        attachmentFile.setDeletedBy(user.getUserName());
        attachmentFile.setDeletedTime(new Date());
        LambdaQueryWrapper<AttachmentFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AttachmentFile::getDeletedFlg, 0);
        queryWrapper.eq(AttachmentFile::getVoucherCode, modelAttach.getId());
        queryWrapper.eq(AttachmentFile::getVoucherType, "3");
        attachmentFileMapper.update(attachmentFile, queryWrapper);
        //插入新附件
        List<FileParams> files = params.getFileList();
        if(CollectionUtil.isNotEmpty(files)){
            for(FileParams file : files){
                AttachmentFile attach = new AttachmentFile();
                attach.setFilename(file.getFileName());
                attach.setFilepath(file.getFilePath());
                //2：桨模的附件
                attach.setVoucherType("3");
                attach.setVoucherCode(modelAttach.getId());
                attachmentFileMapper.insert(attach);
            }
        }
    }

    /**
     * 完成
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param params modelAttach
     */
    @Override
    @Transactional
    public void finishModelAttach(ModelAttachAddParams params){
        ModelAttach modelAttach = params.getModelAttach();
        modelAttach.setStatus(2);
        modelAttach.setStatusName(dictService.findDictLabel("MODEL_ATTACH_STATUS", "2"));
        this.updateById(modelAttach);
        //插入附体图纸附件
        List<FileParams> files = params.getFileList();
        if(CollectionUtil.isNotEmpty(files)){
            for(FileParams file : files){
                AttachmentFile attach = new AttachmentFile();
                attach.setFilename(file.getFileName());
                attach.setFilepath(file.getFilePath());
                //6：附体的图纸文件
                attach.setVoucherType("6");
                attach.setVoucherCode(modelAttach.getId());
                attachmentFileMapper.insert(attach);
            }
        }
    }

    /**
     * 附体企业微信端完成
     * @param params
     */
    @Override
    public void finishForWechat(WechatFinishParams params){
        ModelAttachAddParams param = new ModelAttachAddParams();
        ModelAttach modelAttach = new ModelAttach();
        BeanUtil.copyProperties(params, modelAttach);
        param.setModelAttach(modelAttach);
        param.setFileList(params.getFileList());
        this.finishModelAttach(param);
    }

    /**
     * 逻辑删除
     * @author ganjun
     * @date 2024-11-20 17:18:55
     * @param modelAttach modelAttach
     * @param modelAttachIds modelAttachIds
     */
    @Override
    @Transactional
    public boolean deleteModelAttach(ModelAttach modelAttach,String modelAttachIds) {
        boolean result = false;
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<String> list = Arrays.asList(modelAttachIds.split(StringPool.COMMA));

        modelAttach.setDeletedBy(user.getUserName());
        modelAttach.setDeletedTime(new Date());
        modelAttach.setDeletedFlg(FebsConstant.INVALID);
        int update = this.baseMapper.update(modelAttach,new LambdaQueryWrapper<ModelAttach>().in(ModelAttach::getId,list));
        if (update > 0 ){
            result = true;
        }
        return result;
	}

    /**
    * 物理删除
    * @author ganjun
    * @date 2024-11-20 17:18:55
    * @param modelAttachIds modelAttachIds
    */
    @Override
    @Transactional
    public boolean physicallyDeleteModelAttach(String modelAttachIds) {
        List<String> list = Arrays.asList(modelAttachIds.split(StringPool.COMMA));
        LambdaQueryWrapper<ModelAttach> wapper = new LambdaQueryWrapper<>();
        wapper.in(ModelAttach::getId,list);
        return this.remove(wapper);
    }

    /**
     * 获取项目列表
     * @return
     */
    @Override
    public List<ProjectVO> getProjectList(){
        //获取当前用户id
        ProjectManager pm = new ProjectManager();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        boolean isSysAdmin = isSysAdmin(user.getUserId());
        if(isSysAdmin){
            pm.setUserId(null);
        }else{
            pm.setUserId(user.getUserId());
        }
        List<ProjectManager> pmList = projectManagerService.findProjectManagerList(pm);
        List<String> projCodes = pmList.stream().map(ProjectManager::getProjectCode).collect(Collectors.toList());
        List<ProjectVO> projVOList = new ArrayList<ProjectVO>();
        if(CollectionUtil.isNotEmpty(projCodes)){
            SypqProject projParams = new SypqProject();
            List<SypqProject> projList = projectService.findSypqProjectList(projParams);
            if(CollectionUtil.isNotEmpty(projList)){
                for(SypqProject proj : projList){
                    if(projCodes.contains(proj.getProjectCode())){
                        ProjectVO vo = new ProjectVO();
                        BeanUtil.copyProperties(proj, vo);
                        projVOList.add(vo);
                    }
                }
            }
        }
        return projVOList;
    }

    /**
     * 企业微信端附体列表
     * @return
     */
    @Override
    public List<WechatAttachModelVO> getAttachModelList(WechatModelParams params){
        LambdaQueryWrapper<ModelAttach> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelAttach::getDeletedFlg, 0);
        queryWrapper.orderByDesc(ModelAttach::getCreatedTime);
        //根据来源查询
        if(null != params.getSourceType()){
            queryWrapper.eq(ModelAttach::getSource, params.getSourceType());
        }
        //根据状态查询
        if(null != params.getStatus()){
            List statusList = null;
            if(params.getStatus() == 1){
                statusList = Collections.singletonList(1);
            }else if(params.getStatus() == 3){
                statusList = Collections.singletonList(2);
            }else{
                statusList = Arrays.asList(1,2);
            }
            queryWrapper.in(ModelAttach::getStatus, statusList);
        }

        //角色判断
        CurUserProjInfoVO curUserProjInfoVO = getCurUserProjInfo();
        boolean isSysAdmin = curUserProjInfoVO.isSysAdmin();
        List<String> projCodeList = curUserProjInfoVO.getProjCodeList();
        //根据权限判断可以查看的项目相关的桨模
        if(!isSysAdmin){
            if(CollectionUtil.isNotEmpty(projCodeList)){
                queryWrapper.in(ModelAttach::getProjectCode, projCodeList);
            }else{
                projCodeList.add("0");
                queryWrapper.in(ModelAttach::getProjectCode, projCodeList);
            }
        }

        List<ModelAttach> modelAttachList = this.baseMapper.selectList(queryWrapper);
        List<WechatAttachModelVO> voList = new ArrayList<WechatAttachModelVO>();
        if(CollectionUtil.isNotEmpty(modelAttachList)){
            for(ModelAttach modelAttach : modelAttachList){
                WechatAttachModelVO vo = new WechatAttachModelVO();
                BeanUtil.copyProperties(modelAttach, vo);
                vo.setFileList(this.getModelShipAttachsByAttachId(vo.getId(), ""));
                voList.add(vo);
            }
        }
        return voList;
    }

    /**
     * 角色判断
     * @return
     */
    private CurUserProjInfoVO getCurUserProjInfo(){
        List<String> projCodeList = new ArrayList<String>();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<UserRole> userRoles = userRoleService.getUserRoleListByUserid(user.getUserId());
        boolean isSysAdmin = false;

        boolean isOperator = false;

        if(CollectionUtil.isNotEmpty(userRoles)){
            //判断是否系统管理员
            isSysAdmin = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "1"));
            //判断是否资源管理员
            boolean isResourceAdmin = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "c2331034b20a380bf860b331cdd12619"));
            //判断是否操作员/检验员
            isOperator = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "533f1044ed1db628316a3e7c35305fd8"));
            if(isResourceAdmin){
                List<String> taskProjList = taskMapper.getTaskByRsAdmin(user.getUserId());
                projCodeList.addAll(taskProjList);
            }
        }
        //项目审批人的项目
        SypqProject sypqProject = new SypqProject();
        sypqProject.setAuditorid(user.getUserId());
        List<SypqProject> projs = projectService.findSypqProjectList(sypqProject);
        if(CollectionUtil.isNotEmpty(projs)){
            List<String> auditProjCodeList = projs.stream().map(SypqProject::getProjectCode).collect(Collectors.toList());
            projCodeList.addAll(auditProjCodeList);
        }
        //项目经理的项目
        ProjectManager pm = new ProjectManager();
        pm.setUserId(user.getUserId());
        List<ProjectManager> pmList = projectManagerService.findProjectManagerList(pm);
        List<String> projCodes = pmList.stream().map(ProjectManager::getProjectCode).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(projCodes)){
            projCodeList.addAll(projCodes);
        }
        CurUserProjInfoVO vo = new CurUserProjInfoVO();
        //操作员（实验员）也可以查看所有附体数据
        vo.setSysAdmin(isSysAdmin || isOperator);
        vo.setProjCodeList(projCodeList);

        return vo;
    }

    /**
     * 判断是否系统管理员
     * @param userId
     * @return
     */
    private boolean isSysAdmin(String userId){
        List<UserRole> userRoles = userRoleService.getUserRoleListByUserid(userId);
        boolean isSysAdmin = false;
        if(CollectionUtil.isNotEmpty(userRoles)){
            //判断是否系统管理员
            isSysAdmin = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "1"));

        }
        return isSysAdmin;
    }
}
